//
//  LLTTakePhotoBtn.swift
//  TakePhoto
//
//  Created by 李陆涛 on 2018/7/26.
//  Copyright © 2018年 llt. All rights reserved.
//

import UIKit

protocol LLTTakePhotoBtnDelegate: NSObjectProtocol {
    
    func startRecordingDelegate(_ sender: LLTTakePhotoBtn)
    func stopRecordingDelegate(_ sender: LLTTakePhotoBtn)
    func takePhotoDelegate(_ sender: LLTTakePhotoBtn)
    func videoZoomFactor(_ zoom:CGFloat)
}

class LLTTakePhotoBtn: UIView {
    
    private var centerLayer: CAShapeLayer!
    
    private var textLabel: UILabel!
    private var centerView: UIView!
    
    
    private var viewWidth:CGFloat!
    private var viewCenter:CGPoint!
    
    private var cameraStyle:CameraStyle = .none
    
    private var isRecording:Bool = false
    
    private var originalCenter:CGPoint!
    
    
    weak var delegate: LLTTakePhotoBtnDelegate?
    
    
    override func awakeFromNib() {
         super.awakeFromNib()
        
        initUI()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        initUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        
        
        super.init(coder: aDecoder)
    }
    
    
    private func initUI() {
        
        viewCenter = CGPoint(x:  frame.size.width / 2.0, y: frame.size.height / 2.0)
        viewWidth = frame.size.width
        
        originalCenter = self.center
        
        let r = (viewWidth - 30) / 2.0
        
        let path = bezierPathBy(r, 0.1)
        
        centerLayer = CAShapeLayer()
        centerLayer.path = path.cgPath
        centerLayer.fillRule = "even-odd"
        centerLayer.fillColor = UIColor.red.cgColor
        self.layer.addSublayer(centerLayer)
        
        centerView = UIView(frame: CGRect(x: viewCenter.x - r, y: viewCenter.y - r, width: 2 * r, height: 2 * r))
        centerView.layer.cornerRadius = r;
        
        centerView.backgroundColor = UIColor.red
        
        self.addSubview(centerView)
        
        textLabel = UILabel()
        textLabel.textColor = UIColor.white
        textLabel.text = "按住"
        
        textLabel.font = UIFont.systemFont(ofSize: 14)
        textLabel.sizeToFit()
        textLabel.center = viewCenter
        
        self.addSubview(textLabel)
        
        changeStyle(.pressVideo)
        
    }
    
    
    private func bezierPathBy(_ path1Radius:CGFloat,_ path2Radius:CGFloat?) -> UIBezierPath {
        
        let path1 = UIBezierPath(arcCenter: viewCenter, radius: path1Radius, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: false)
        
        guard let path2Radius = path2Radius else { return path1 }
        
        let path2 = UIBezierPath(arcCenter: viewCenter, radius: path2Radius, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: false)
        
        path1.append(path2)
        
        return path1
    }
    
    private func basicAnimation(layer:CALayer,
                                fromValue:CGPath,
                                toValue:CGPath,
                                duration:CFTimeInterval,
                                repeatCount:Float,
                                autoreverses:Bool) {
        
        let pathAnimation = CABasicAnimation(keyPath: "path")
        
        pathAnimation.fromValue = fromValue
        
        pathAnimation.toValue = toValue
        pathAnimation.autoreverses = autoreverses
        pathAnimation.duration = duration
        pathAnimation.repeatCount = repeatCount
        pathAnimation.fillMode = kCAFillModeForwards
        pathAnimation.isRemovedOnCompletion = false
        
        layer.add(pathAnimation, forKey: "path")
    }
    
    func changeStyle(_ style : CameraStyle) {
        
        if style == cameraStyle {
            
            return
        }
        
        switch style {
        case .clickVideo:
            
            centerLayer.fillColor = UIColor.red.withAlphaComponent(0.3).cgColor
            centerView.backgroundColor = UIColor.red
            textLabel.isHidden = true;
            centerView.isHidden = false
            if cameraStyle == .pressVideo || cameraStyle == .none {
                
                showClickView()
            }
            
        case .pressVideo:
            
            self.originalCenter = self.center
            self.centerLayer.fillColor = UIColor.red.cgColor
            centerView.backgroundColor = UIColor.red
            textLabel.isHidden = false;
            showPressView()
            
        case .takePhoto:
            
            centerLayer.fillColor = UIColor.white.withAlphaComponent(0.3).cgColor
            centerView.backgroundColor = UIColor.white
            centerView.isHidden = false
            textLabel.isHidden = true;
            
            if cameraStyle == .pressVideo || cameraStyle == .none {
                
                showClickView()
            }
            
        default:
            break
        }
        
        cameraStyle = style;
    }
    
    func forceStopRecording() {
        
        if isRecording {
            
            if cameraStyle == .pressVideo {
                
                endPressVideo()
            } else {
                
                recordingOperation()
            }
        }
        
    }
    
    private func showClickView() {
        
        let r1 = (viewWidth - 20) / 2.0
        let r2 = (viewWidth - 30) / 2.0
        
        let path1 = bezierPathBy(r2, 0.1)
        let path2 = bezierPathBy(r1, r2)
        
        basicAnimation(layer: centerLayer,
                       fromValue: path1.cgPath,
                       toValue: path2.cgPath,
                       duration: 0.25,
                       repeatCount: 1,
                       autoreverses: false)
        
        let r3 = (viewWidth - 40) / 2.0
        
        UIView.animate(withDuration: 0.25) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            self.centerView.bounds = CGRect(x: 0, y: 0, width: 2 * r3, height: 2 * r3)
            self.centerView.layer.cornerRadius = r3;
        }
    }
    
    private func showPressView() {
        
        let r1 = (viewWidth - 20) / 2.0
        let r2 = (viewWidth - 30) / 2.0
        
        let path1 = bezierPathBy(r2, 0.1)
        let path2 = bezierPathBy(r1, r2)
        
        basicAnimation(layer: centerLayer,
                       fromValue: path2.cgPath,
                       toValue: path1.cgPath,
                       duration: 0.25,
                       repeatCount: 1,
                       autoreverses: false)
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.25) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            if self.cameraStyle == .pressVideo {
                
                self.centerView.isHidden = true
            }
        }
    }
    
    
    var startTime:TimeInterval = 0.0
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        
        if cameraStyle == .pressVideo {
            
            guard let touch = touches.first else {
                
                return
            }
            
            let point = touch.location(in: self.superview)
            
            self.center = point
            
            
            startTime = Date.init().timeIntervalSince1970
            
            recordingOperation()
            
        }
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        if cameraStyle != .pressVideo {
            
            return
        }
        
        guard let touch = touches.first else {
            return
        }
        
        let point = touch.location(in: self.superview)
        
        self.center = point
        
        let disY = self.originalCenter.y - point.y
        
        var scale = disY / self.originalCenter.y + 1.0

        if scale < 1.0 {
            
            scale = 1.0
        }
        
        self.delegate?.videoZoomFactor(scale)
        
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        endPressVideo()
        
    }
    
    private func endPressVideo() {
        
        if cameraStyle == .pressVideo {
            
            self.delegate?.videoZoomFactor(1.0)
            
            UIView.animate(withDuration: 0.25) {
                
                [weak self] in
                guard let `self` = self else { return }
                
                self.center = self.originalCenter
            }
            
            let endTime = Date.init().timeIntervalSince1970
            
            let time = endTime - startTime
            
            if time < 1 {
                
            }
        }
        
        recordingOperation()
    }
    
    
    private func recordingOperation() {
        
        switch cameraStyle {
            
        case .takePhoto:
            
            self.delegate?.takePhotoDelegate(self)
            break
        case .clickVideo:
            
            if isRecording {
                
                isRecording = false
                self.delegate?.stopRecordingDelegate(self)
            } else {
                
                isRecording = true
                self.delegate?.startRecordingDelegate(self)
            }
            
            clickAnimation(isRecording)
            
        case .pressVideo:
            
            if isRecording {
            
                isRecording = false
                self.delegate?.stopRecordingDelegate(self)
                
            } else {

                isRecording = true
                self.delegate?.startRecordingDelegate(self)
            }
            
            pressAnimation(isRecording)
        default:
            break
        }
    }
    
    
    private func pressAnimation(_ isStart:Bool) {
        
        let r1 = (viewWidth - 20) / 2.0
        
        let r3 = viewWidth / 2.0
        let r4 = (viewWidth + 10) / 2.0
        
        let path1 = bezierPathBy(r1, 0.1)
        let path2 = bezierPathBy(r4, r3)
        
        
        var fromValue = path1
        var toValue = path2
        
        
        if !isStart {
            
            fromValue = path2
            toValue = path1
        }
        
        basicAnimation(layer: centerLayer,
                       fromValue: fromValue.cgPath,
                       toValue: toValue.cgPath,
                       duration: 0.5,
                       repeatCount: 1,
                       autoreverses: false)
        
        UIView.animate(withDuration: 0.25) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            self.textLabel.alpha = isStart ? 0.0 : 1.0
        }
        
        if !isStart {
            return
        }
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            if (self.isRecording) {
                
                self.breatheAnimation()
            }
        }
    }
    
    
    private func clickAnimation(_ isStart:Bool) {
        
        let r1 = (viewWidth - 20) / 2.0
        let r2 = (viewWidth - 30) / 2.0
        
        let r3 = viewWidth / 2.0
        let r4 = (viewWidth + 10) / 2.0
        
        let path1 = bezierPathBy(r1, r2)
        let path2 = bezierPathBy(r4, r3)
        
        var fromValue = path1
        var toValue = path2
        
        
        if !isStart {
            
            fromValue = path2
            toValue = path1
        }
        
        
        basicAnimation(layer: centerLayer,
                       fromValue: fromValue.cgPath,
                       toValue: toValue.cgPath,
                       duration: 0.5,
                       repeatCount: 1,
                       autoreverses: false)
        
        let r5 = isStart ?  (viewWidth / 3) / 2.0 : (viewWidth - 40) / 2.0
        
        UIView.animate(withDuration: 0.25) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            self.centerView.bounds = CGRect(x: 0, y: 0, width: r5 * 2, height: r5 * 2)
            self.centerView.layer.cornerRadius = isStart ? 5 : r5
        }

        if !isStart {
            return
        }
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            if (self.isRecording) {
                
                self.breatheAnimation()
            }
        }
    }

    private func breatheAnimation() {
        
        let r1 = viewWidth / 2.0
        let r2 = (viewWidth + 10) / 2.0
        let r3 = (viewWidth - 10) / 2.0
        
        let path1 = bezierPathBy(r2, r1)
        let path2 = bezierPathBy(r2, r3)
        
        basicAnimation(layer: centerLayer,
                       fromValue: path1.cgPath,
                       toValue: path2.cgPath,
                       duration: 0.5,
                       repeatCount: MAXFLOAT,
                       autoreverses: true)
    }
}




